package com.czwj.action;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.czwj.annotation.SystemControllerLog;
import com.czwj.entities.Company;
import com.czwj.entities.Duty2;
import com.czwj.entities.Duty3;
import com.czwj.entities.Form;
import com.czwj.entities.ProjectItem;
import com.czwj.entities.UserInfo;
import com.czwj.service.CompanyService;
import com.czwj.service.Duty2Service;
import com.czwj.service.Duty3Service;
import com.czwj.service.FormService;
import com.czwj.service.ProjectItemService;
import com.czwj.service.UserInfoService;
import com.czwj.util.CipherUtil;
import com.czwj.util.GsonUtil;
import com.czwj.util.TextUtil;
import com.czwj.util.WechatUtil;

@Controller
public class LoginAction{
	public final String LOGOUT = "logout";
	@Resource
	UserInfoService userinfoService;
	@Resource
	CompanyService companyService;
	@Resource
	FormService formSerivce;
	@Resource
	ProjectItemService projectItemService;
	@Resource
	Duty2Service duty2Service;
	@Resource
	Duty3Service duty3Service;
	
	@Value("${appid}")
	private String appid;
	@Value("${appsecret}")
	private String appsecret;
	@Value("${redirect_uri}")
	private String redirect_uri;
	private Cookie cookie;
	
	@SystemControllerLog(description = "浏览器端登录")
	@RequestMapping(value = "/login.do",method = RequestMethod.POST)
	public ModelAndView Login(String username,String password,String mobile,HttpServletRequest request,
			HttpServletResponse response){
		ModelAndView mav = new ModelAndView();
		Subject currentUser = SecurityUtils.getSubject();
		if(TextUtil.isNotEmpty(username)){
			UserInfo user = userinfoService.findByUserName(username);
			if(user == null){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","用户名或密码错误");
				mav.setViewName("login");
				return mav;
			}
			if(user.getId() != 0){
				if(user.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
				Company company = companyService.selectByPrimaryKey(user.getCompanyid());
				if(company.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
			}
			try{
				UsernamePasswordToken token = new UsernamePasswordToken(username,CipherUtil.encrypt(password));
//				UsernamePasswordToken token = new UsernamePasswordToken(username,password);
				currentUser.login(token);
				currentUser.getSession().setAttribute("userInfo",user);
				currentUser.getSession().setAttribute("key","pc_" + username);
				// currentUser.getSession().setAttribute("subject", currentUser);
				mav.setViewName("redirect:main.do");
				List<Session> loginedList = getLoginedSession("pc_" + username);
				for(Session session:loginedList){
					if(currentUser.getSession().getId() != session.getId()){
						session.stop();
					}
				}
			}
			catch(Exception e){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","用户名或密码错误");
				mav.setViewName("login");
			}
			return mav;
		}else if(TextUtil.isNotEmpty(mobile)){
			UserInfo user = userinfoService.searchbymobile(mobile);
			if(user == null){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","手机号或密码错误");
				mav.setViewName("login");
				return mav;
			}
			if(user.getId() != 0){
				if(user.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
				Company company = companyService.selectByPrimaryKey(user.getCompanyid());
				if(company.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
			}
			try{
				String pwd = CipherUtil.decrypt(user.getPassword());
				if(password.equals(pwd)){
					UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),
							CipherUtil.encrypt(password));
					currentUser.login(token);
					currentUser.getSession().setAttribute("userInfo",user);
					currentUser.getSession().setAttribute("key","pc_" + username);
					// currentUser.getSession().setAttribute("subject", currentUser);
					mav.setViewName("redirect:main.do");
					List<Session> loginedList = getLoginedSession("pc_" + username);
					for(Session session:loginedList){
						if(currentUser.getSession().getId() != session.getId()){
							session.stop();
						}
					}
				}else{
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户名或密码错误");
					mav.setViewName("login");
					return mav;
				}
			}
			catch(Exception e){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","用户名或密码错误");
				mav.setViewName("login");
			}
			return mav;
		}else{
			mav.addObject("username",username);
			mav.addObject("mobile",mobile);
			mav.addObject("password",password);
			mav.addObject("err_msg","用户名或密码错误");
			mav.setViewName("login");
			return mav;
		}
	}
	
	@RequestMapping("/main.do")
	public ModelAndView main(){
		ModelAndView mav = new ModelAndView();
		Subject currentUser = SecurityUtils.getSubject();
		UserInfo userInfo = (UserInfo)currentUser.getSession().getAttribute("userInfo");
		int roleid = userInfo.getRoleid();
		if(roleid==1||roleid==2){
			List<ProjectItem> list = projectItemService.searchByCreater(userInfo.getId());
			mav.addObject("ProjectItems", list);
		}else if (roleid==3) {
			List<Duty2> list = duty2Service.searchByUser(userInfo.getId());
			mav.addObject("ProjectItems", list);
		}else if (roleid==4) {
			List<Duty3> list = duty3Service.searchByUser(userInfo.getId());
			mav.addObject("ProjectItems", list);
		}
		mav.setViewName("main");
		return mav;
	}
	
	@RequestMapping(value = "/app/index")
	public ModelAndView appindex(HttpServletRequest request,
			@RequestParam(value = "mobile",required = true) String mobile){
		ModelAndView mav = new ModelAndView();
		UserInfo userInfo = userinfoService.searchbymobile(mobile);
		if(userInfo == null){
			mav.addObject("err_msg","手机号码未录入,请在浏览器端修改您的手机号码");
			mav.setViewName("/app/login");
			return mav;
		}else{
			if(userInfo.getStatus() == 3){
				mav.setViewName("/app/error4");
			}
			Company company = companyService.selectByPrimaryKey(userInfo.getCompanyid());
			if(company.getStatus() == 3){
				mav.setViewName("/app/error4");
			}
			Subject currentUser = SecurityUtils.getSubject();
			UsernamePasswordToken token = new UsernamePasswordToken(userInfo.getUsername(),userInfo.getPassword());
			currentUser.login(token);
			currentUser.getSession().setAttribute("userInfo",userInfo);
			// currentUser.getSession().setAttribute("subject", currentUser);
			currentUser.getSession().setAttribute("key","app_" + userInfo.getUsername());
			List<Session> loginedList = getLoginedSession("app_" + userInfo.getUsername());
			for(Session session:loginedList){
				if(currentUser.getSession().getId() != session.getId()){
					session.stop();
				}
			}
			mav.setViewName("app/menu1");
		}
		return mav;
	}
	
	@RequestMapping(value = "/app/login.do",method = RequestMethod.POST)
	public ModelAndView applogin(String username,String password,String mobile,HttpServletRequest request,
			HttpServletResponse response){
		ModelAndView mav = new ModelAndView();
		Subject currentUser = SecurityUtils.getSubject();
		if(TextUtil.isNotEmpty(username)){
			UserInfo user = userinfoService.findByUserName(username);
			if(user == null){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","用户名或密码错误");
				mav.setViewName("login");
				return mav;
			}
			if(user.getId() != 0){
				if(user.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
				Company company = companyService.selectByPrimaryKey(user.getCompanyid());
				if(company.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
			}
			try{
				UsernamePasswordToken token = new UsernamePasswordToken(username,CipherUtil.encrypt(password));
				currentUser.login(token);
				currentUser.getSession().setAttribute("userInfo",user);
				currentUser.getSession().setAttribute("key","app_" + username);
				// currentUser.getSession().setAttribute("subject", currentUser);
				mav.setViewName("app/menu1");
				List<Session> loginedList = getLoginedSession("app_" + username);
				for(Session session:loginedList){
					if(currentUser.getSession().getId() != session.getId()){
						session.stop();
					}
				}
			}
			catch(Exception e){
				mav.addObject("username",username);
				mav.addObject("password",password);
				mav.addObject("err_msg","用户名或密码错误");
				mav.setViewName("app/login");
			}
			return mav;
		}else if(TextUtil.isNotEmpty(mobile)){
			UserInfo user = userinfoService.searchbymobile(mobile);
			if(user == null){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","手机号或密码错误");
				mav.setViewName("login");
				return mav;
			}
			if(user.getId() != 0){
				if(user.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
				Company company = companyService.selectByPrimaryKey(user.getCompanyid());
				if(company.getStatus() == 3){
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户未激活，请联系系统管理员。");
					mav.setViewName("login");
					return mav;
				}
			}
			try{
				String pwd = CipherUtil.decrypt(user.getPassword());
				if(password.equals(pwd)){
					UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),
							CipherUtil.encrypt(password));
					currentUser.login(token);
					currentUser.getSession().setAttribute("userInfo",user);
					currentUser.getSession().setAttribute("key","pc_" + username);
					// currentUser.getSession().setAttribute("subject", currentUser);
					mav.setViewName("app/menu1");
					List<Session> loginedList = getLoginedSession("pc_" + username);
					for(Session session:loginedList){
						if(currentUser.getSession().getId() != session.getId()){
							session.stop();
						}
					}
				}else{
					mav.addObject("username",username);
					mav.addObject("mobile",mobile);
					mav.addObject("password",password);
					mav.addObject("err_msg","用户名或密码错误");
					mav.setViewName("login");
					return mav;
				}
			}
			catch(Exception e){
				mav.addObject("username",username);
				mav.addObject("mobile",mobile);
				mav.addObject("password",password);
				mav.addObject("err_msg","用户名或密码错误");
				mav.setViewName("login");
			}
			return mav;
		}else{
			mav.addObject("username",username);
			mav.addObject("mobile",mobile);
			mav.addObject("password",password);
			mav.addObject("err_msg","用户名或密码错误");
			mav.setViewName("login");
			return mav;
		}
	}
	
	@RequestMapping(value = "/app/onLogin",method = RequestMethod.GET)
	@ResponseBody
	public String appOnLogin(@RequestParam(value = "code",required = true) String code,
			@RequestParam(value = "iv",required = true) String iv,
			@RequestParam(value = "encryptedData",required = true) String encryptedData){
		String login_url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + appsecret
				+ "&js_code=" + code + "&grant_type=authorization_code";
		try{
			URL url = new URL(login_url);
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();
			BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String result = "";
			String line;
			while((line = in.readLine()) != null){
				result += line;
			}
			// System.err.println(result);
			// Code2SessionResult code2SessionResult = GsonUtil.jsonStrToObject(result, Code2SessionResult.class);
			// System.err.println(WechatUtil.decryptData(encryptedData, code2SessionResult.getSession_key(), iv));
			Map<String,Object> map = GsonUtil.getKeytoValueFromJsonObject(result);
			if(map.get("session_key") == null){
				return "{\"phoneNumber\":null}";
			}
			String string = WechatUtil.decryptData(encryptedData,map.get("session_key").toString(),iv);
			Map<String,Object> map2 = GsonUtil.getKeytoValueFromJsonObject(string);
			String phone = map2.get("phoneNumber").toString();
			UserInfo userInfo = userinfoService.searchbymobile(phone);
			if(userInfo != null && userInfo.getOpenid() != map.get("openid").toString()){
				userInfo.setOpenid(map.get("openid").toString());
				userinfoService.update(userInfo);
			}
			return string;
		}
		catch(Exception e){
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "{\"phoneNumber\":null}";
		}
	}
	
	@RequestMapping(value = "/app/submitformid",method = RequestMethod.POST)
	@ResponseBody
	public String submitformid(@RequestParam(value = "formId") String formId,
			@RequestParam(value = "mobile") String mobile) throws Exception{
		UserInfo userInfo = userinfoService.searchbymobile(mobile);
		// formSerivce.deletebyuser(userInfo.getId());
		Form form = new Form(userInfo.getId(),formId);
		formSerivce.insertSelective(form);
		// WechatUtil.pushMessage(userInfo.getOpenid(),"g3kPO4z_S29Vc2k5S3BxAQeNU-4cd5HU0JcGpbpMUC8",formId);
		return "{\"res\":success}";
	}
	
	// private List<Session> getLoginedSession(Subject currentUser) {
	// Collection<Session> list = ((DefaultSessionManager) ((DefaultSecurityManager) SecurityUtils
	// .getSecurityManager()).getSessionManager()).getSessionDAO()
	// .getActiveSessions();
	// List<Session> loginedList = new ArrayList<Session>();
	// UserInfo loginUser = (UserInfo) currentUser.getPrincipal();
	// for (Session session : list) {
	// Subject s = new Subject.Builder().session(session).buildSubject();
	// if (s.isAuthenticated()) {
	// UserInfo user = (UserInfo) s.getPrincipal();
	//
	// if (user.getUsername().equalsIgnoreCase(loginUser.getUsername())) {
	// if (!session.getId().equals(
	// currentUser.getSession().getId())) {
	// loginedList.add(session);
	// }
	// }
	// }
	// }
	// return loginedList;
	// }
	private List<Session> getLoginedSession(String key){
		Collection<Session> list = ((DefaultSessionManager)((DefaultSecurityManager)SecurityUtils.getSecurityManager())
				.getSessionManager()).getSessionDAO().getActiveSessions();
		List<Session> loginedList = new ArrayList<Session>();
		for(Session session:list){
			if(session.getAttribute("key") != null && session.getAttribute("key").toString().equals(key)){
				// System.err.println(session.getAttribute("key").toString());
				loginedList.add(session);
			}
		}
		return loginedList;
	}
}
